Skip to content

You can now work on several branches of a project at once, each in its…#414

Merged
inkeep-oss-sync[bot] merged 1 commit into
mainfrom
copybara/sync
Jul 1, 2026
Merged

You can now work on several branches of a project at once, each in its…#414
inkeep-oss-sync[bot] merged 1 commit into
mainfrom
copybara/sync

Conversation

@inkeep-oss-sync

Copy link
Copy Markdown
Contributor

You can now work on several branches of a project at once, each in its own window. The project switcher in the sidebar footer (and the File menu) has a new Worktrees section: pick a branch to open its worktree in a new window — if it doesn't have one yet, OpenKnowledge creates it on demand — or choose "New worktree…" to start a fresh branch. Worktrees are stored inside the project under .ok/worktrees/ and kept out of git status automatically, so each window stays fully isolated (its own editor and server) without touching your working copy.

* feat(open-knowledge): worktree selector for isolated per-branch windows

Adds a worktree selector to the desktop app so you can work on several
branches of a project at once, each in its own window with its own editor
and server. Surfaced in two places (PRD-7231):

- The sidebar project switcher gains a Worktrees section listing local
  branches and their worktrees, with the current window and main worktree
  flagged. Picking a branch opens its worktree in a new window, creating one
  on demand under .ok/worktrees/<branch> if it does not exist yet. A "New
  worktree" item opens a dialog to start a fresh branch off the current one.
- The File menu gains "New worktree" and "Switch worktree" items that drive
  the same renderer surface via menu actions.

Desktop main enumerates branches and worktrees and runs git worktree add,
auto-locating each worktree inside the project and excluding .ok/worktrees/
from the parent repo git status through .git/info/exclude so the nested
worktree never shows up as untracked. Opening a worktree reuses the existing
project-open path with a new 'worktree' entry point; because the worktree
carries the committed .ok/config.yml it resolves as a managed project and
opens with no consent dialog. There is no in-place git checkout, so the live
editor and auto-committing shadow repo are never disturbed.

list and create ride one consolidated IPC channel (ok:worktree:dispatch),
following the ok:sharing:dispatch precedent to respect the hand-rolled
channel cap. The pure branch/worktree merge and path logic live in core with
unit tests; the git IO and selector UI are covered by integration and DOM
tests.

* fix(open-knowledge): worktree IPC no-git logging + stderr classify types

CI caught two issues on the worktree selector:
- worktree-service classifyAddError reached err.stderr through optional
  chaining (a biome --unsafe rewrite of the original non-null assertion),
  making raw possibly-undefined and failing desktop typecheck (TS18048).
  Rewritten with a stable local + Buffer.isBuffer guard so no assertion is
  needed and the unsafe fix cannot reintroduce it.
- The ok:worktree:dispatch handler returned { ok: false, reason: no-git }
  without a paired logIpcError call, failing the ipc-log-coverage meta-test.
  Added the logIpcError call in the guard block.

* fix(open-knowledge): guard project switcher against Electron open-click fall-through

On the Electron host Chromium delivers no real pointerdown to the renderer, so
the click that opens the project-switcher dropdown can fall through onto a menu
row and immediately fire its onSelect — a project opens and the menu flickers
shut. Swallow any row selection landing within SELECT_GUARD_MS of the menu
opening (preventDefault keeps the menu open); a deliberate later click still
works. Applies to recents, the project actions, and the new worktree rows.
Gated on the Electron host so browsers keep normal behavior.

* feat(open-knowledge): enrich recents with worktree relationship + keep project as launch default

Backend for first-class nested worktrees (PRD-7231): ok:project:list-recent
now annotates each present recent with { gitCommonDir, mainRoot, isLinkedWorktree,
branch } via a memoized single git rev-parse per path, so the renderer can group
linked worktrees under their main project. Opening a worktree still records it in
recents but sets lastOpenedProject to the main repo root, so the launch default
stays the project rather than a specific branch's window.

* feat(open-knowledge): cached non-blocking worktree store for the current project

Module-level store (mirrors current-branch-store) holding the current window's
WorktreeSelectorModel, fetched once via bridge.worktree.list() and shared across
the switcher, command palette, and search via useSyncExternalStore. Repeat reads
are cache-served (instant, non-blocking); refresh() re-fetches after a create; a
failed/null fetch keeps the prior cache. PRD-7231 FR7.

* feat(open-knowledge): pure repo-grouping of recents for nested worktrees

* feat(open-knowledge): nested worktree submenu, switcher search, Cmd-K worktrees

Make worktrees first-class in the project switcher. Recents group by repo:
a project with opened worktrees exposes them in a submenu (project row +
each worktree), a project with none stays a flat row. Typing in the switcher
searches across recent projects, opened worktrees, and the current project's
un-opened branches (create-on-demand via the cached worktree store). The
Cmd-K palette gains a Worktrees group over the same cached model.

Replaces the flat WorktreeSwitcherSection with RecentProjectsMenu; the
top-level "New worktree" item stays for git projects. One git spawn total,
shared across surfaces; async arrival fills a stable region without reflow.

* feat(open-knowledge): dual-mode New Worktree dialog (create or check out a branch)

The New Worktree dialog now disambiguates the typed branch against the
project's local branches: an unknown name creates a fresh branch off the
current one, a known name checks that existing branch out as a worktree
(createBranch false, no base). Existing branches surface in a datalist so
selection is discoverable, the caption + confirm label adapt to the mode,
and the current window's cached worktree model refreshes after a create.

* docs(open-knowledge): align worktree-selector SPEC with shipped submenu/search/dialog

* fix(open-knowledge): use <Trans> not interpolated t`` in worktree submenu

The React Compiler cannot lower a tagged template with interpolations
(`t`Open ${name}``), and it only fails in the vite build's Babel pass — not
tsc or bun tests — so it slipped local checks and broke the app build (and
every downstream OK Validation job). Switch the "Open <project>" label to
the <Trans> component, which handles interpolation compiler-safely.

* style(open-knowledge): biome-format worktree recents test files

* docs(open-knowledge): drop FR7 tag from worktree-store comment (comment-discipline)

* fix(open-knowledge): coalesce mid-flight worktree-store refresh + cover create error path

Addresses PR review: refresh() (fired right after worktree.create) was dropped
if it landed while the bootstrap load was still in-flight, so a just-created
worktree could miss the current window's cache until remount. Queue one
follow-up load instead. Also add the flagged error-path test: a failed
create-on-demand toasts and opens no window.

GitOrigin-RevId: 093eba067e2497015f4800bb3b17fa3995d4e6c3

@inkeep-internal-ci inkeep-internal-ci Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Automated approval from agents-private public-mirror-sync (run: https://github.com/inkeep/agents-private/actions/runs/28509679656). Source of truth is the monorepo; direct edits on inkeep/open-knowledge are overwritten on next sync.

@inkeep-oss-sync
inkeep-oss-sync Bot merged commit ceed8fd into main Jul 1, 2026
2 checks passed
@inkeep-oss-sync
inkeep-oss-sync Bot deleted the copybara/sync branch July 1, 2026 10:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant